﻿// MainFrm.cpp: CMainFrame 类的实现
//

#include "pch.h"
#include "framework.h"
#include "HexEditor.h"

#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#include "CEditPage.h"
#include "CEditSheet.h"

extern CEditSheet* g_pEditSheet;
extern bool g_bInit;
CMenu* pDynamicStaticMenu = nullptr;
extern CStatusBar g_wndStatusBar;
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
	ON_WM_CREATE()
	ON_WM_MOVE()
	ON_WM_SIZE()
	ON_COMMAND(ID_DYNAMIC, &CMainFrame::OnToggleDynamic)
	ON_COMMAND(ID_STATIC, &CMainFrame::OnToggleStatic)
END_MESSAGE_MAP()

static UINT indicators[] =
{
	ID_SEPARATOR,           // 状态行指示器
	ID_INDICATOR_CUR_SIZE,
	ID_INDICATOR_CUR_POS,
	ID_INDICATOR_BEG_END,
};

// CMainFrame 构造/析构

void CMainFrame::OnMove(int x, int y) {
	CFrameWnd::OnMove(x, y);

	if (!g_bInit) {
		return;
	}
	if (g_pEditSheet && g_pEditSheet->GetSafeHwnd()) {
		CEditPage* page = (CEditPage*)g_pEditSheet->GetActivePage();
		if (page && page->m_bInitialized) {
			if (page->m_pMenuWnd) {
				delete page->m_pMenuWnd;
				page->m_pMenuWnd = nullptr;
			}
		}
	}
}

CMainFrame::CMainFrame() noexcept {
	// TODO: 在此添加成员初始化代码
}

CMainFrame::~CMainFrame() {
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {
	if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
		!m_wndToolBar.LoadToolBar(IDR_MAINFRAME)) {
		TRACE0("未能创建工具栏\n");
		return -1;      // 未能创建
	}

	if (!g_wndStatusBar.Create(this)) {
		TRACE0("未能创建状态栏\n");
		return -1;      // 未能创建
	}
	g_wndStatusBar.SetIndicators(indicators, sizeof(indicators) / sizeof(UINT));
	UpdateStatusBar();
	// TODO: 如果不需要可停靠工具栏，则删除这三行
	m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
	EnableDocking(CBRS_ALIGN_ANY);
	DockControlBar(&m_wndToolBar);
	this->SetWindowText(_T("我的窗口标题"));

	return 0;
}
void CMainFrame::OnSize(UINT nType, int cx, int cy) {
	CFrameWnd::OnSize(nType, cx, cy);

	// 调整状态栏的大小和部分宽度
	if (::IsWindow(g_wndStatusBar.m_hWnd)) {
		CRect statusRect;
		g_wndStatusBar.GetWindowRect(&statusRect);
		int statusBarHeight = statusRect.Height();

		g_wndStatusBar.SetWindowPos(NULL, 0, cy - statusBarHeight, cx, statusBarHeight, SWP_NOZORDER | SWP_NOACTIVATE);
		UpdateStatusBar();
	}
}

void CMainFrame::UpdateStatusBar() {
	if (!::IsWindow(g_wndStatusBar.m_hWnd))
		return;

	CRect rect;
	GetClientRect(&rect);

	// 获取DC并选择状态栏的字体
	CDC* pDC = g_wndStatusBar.GetDC();
	CFont* pFont = g_wndStatusBar.GetFont();
	CFont* pOldFont = pDC->SelectObject(pFont);

	// 测量文本的宽度
	CSize sizePane1 = pDC->GetTextExtent(g_wndStatusBar.GetPaneText(1));
	CSize sizePane2 = pDC->GetTextExtent(g_wndStatusBar.GetPaneText(2));
	CSize sizePane3 = pDC->GetTextExtent(g_wndStatusBar.GetPaneText(3));

	// 恢复DC
	pDC->SelectObject(pOldFont);
	g_wndStatusBar.ReleaseDC(pDC);

	// 设置状态栏部分的宽度
	int paneWidths[3];
	paneWidths[0] = sizePane1.cx + 20; // 给文本留一些额外的空间
	paneWidths[1] = sizePane2.cx + 20;
	paneWidths[2] = sizePane3.cx + 50;

	// 计算总宽度
	int totalWidth = paneWidths[0] + paneWidths[1] + paneWidths[2];

	// 确保状态栏部分宽度之和不超过窗口宽度
	int availableWidth = rect.Width() - totalWidth;
	if (availableWidth > 0) {
		// 设置前三个部分的宽度为固定宽度
		g_wndStatusBar.SetPaneInfo(1, g_wndStatusBar.GetItemID(1), SBPS_NORMAL, paneWidths[0]);
		g_wndStatusBar.SetPaneInfo(2, g_wndStatusBar.GetItemID(2), SBPS_NORMAL, paneWidths[1]);
		g_wndStatusBar.SetPaneInfo(3, g_wndStatusBar.GetItemID(3), SBPS_NORMAL, paneWidths[2]);

		// 设置第一个部分的宽度为剩余的宽度
		g_wndStatusBar.SetPaneInfo(0, g_wndStatusBar.GetItemID(0), SBPS_STRETCH, availableWidth);
	}
	else {
		// 确保每个部分至少有一些宽度
		int remainingWidth = rect.Width() - (paneWidths[0] + paneWidths[1]);
		paneWidths[2] = max(remainingWidth, 20);

		// 设置前三个部分的宽度为固定宽度
		g_wndStatusBar.SetPaneInfo(1, g_wndStatusBar.GetItemID(1), SBPS_NORMAL, paneWidths[0]);
		g_wndStatusBar.SetPaneInfo(2, g_wndStatusBar.GetItemID(2), SBPS_NORMAL, paneWidths[1]);
		g_wndStatusBar.SetPaneInfo(3, g_wndStatusBar.GetItemID(3), SBPS_NORMAL, paneWidths[2]);

		// 设置第一个部分的宽度为剩余的宽度
		g_wndStatusBar.SetPaneInfo(0, g_wndStatusBar.GetItemID(0), SBPS_STRETCH, 20);
	}

	g_wndStatusBar.Invalidate();
	g_wndStatusBar.UpdateWindow();
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs) {
	if (!CFrameWnd::PreCreateWindow(cs))
		return FALSE;
	// TODO: 在此处通过修改
	//  CREATESTRUCT cs 来修改窗口类或样式
	// 设置窗口大小和位置

	cs.cx = 750;   // 窗口宽度
	cs.cy = 950;   // 窗口高度
	cs.x = 500; // 使用默认位置（通常位于屏幕中心）
	cs.y = 60;

	return TRUE;
}

// CMainFrame 诊断

#ifdef _DEBUG
void CMainFrame::AssertValid() const {
	CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const {
	CFrameWnd::Dump(dc);
}
#endif //_DEBUG

// CMainFrame 消息处理程序

BOOL CMainFrame::IsMenuItemChecked(UINT nID) {
	CMenu* pMenu = GetMenu();
	if (pMenu) {
		// 遍历主菜单中的各个子菜单，查找指定ID的菜单项
		for (int i = 0; i < pMenu->GetMenuItemCount(); ++i) {
			CMenu* pSubMenu = pMenu->GetSubMenu(i);
			if (pSubMenu) {
				UINT state = pSubMenu->GetMenuState(nID, MF_BYCOMMAND);
				if (state != (UINT)-1) {
					return (state & MF_CHECKED) != 0;
				}
			}
		}
	}
	return FALSE;
}

BOOL CMainFrame::IsSubMenuItemChecked(CMenu* pSubMenu, UINT nID) {
	if (pSubMenu) {
		UINT state = pSubMenu->GetMenuState(nID, MF_BYCOMMAND);
		if (state != (UINT)-1) {
			return (state & MF_CHECKED) != 0;
		}
	}
	return FALSE;
}

BOOL CMainFrame::IsDynamicChecked() {
	CMenu* g_pMenu = GetMenu();
	if (g_pMenu) {
		// 查找 "编辑" 菜单
		CMenu* pEditMenu = nullptr;
		pEditMenu = g_pMenu->GetSubMenu(2);
		if (pEditMenu) {
			// 查找 "右键动态或静态" 子菜单

			pDynamicStaticMenu = pEditMenu->GetSubMenu(2);
			if (pDynamicStaticMenu) {
				// 判断 "动态" 菜单项是否被勾选
				return IsSubMenuItemChecked(pDynamicStaticMenu, ID_DYNAMIC);
			}
		}
	}
	return FALSE;
}

BOOL CMainFrame::IsStaticChecked() {
	CMenu* g_pMenu = GetMenu();
	if (g_pMenu) {
		// 查找 "编辑" 菜单
		CMenu* pEditMenu = nullptr;
		pEditMenu = g_pMenu->GetSubMenu(2);
		if (pEditMenu) {
			// 查找 "右键动态或静态" 子菜单

			pDynamicStaticMenu = pEditMenu->GetSubMenu(2);
			if (pDynamicStaticMenu) {
				// 判断 "动态" 菜单项是否被勾选
				return IsSubMenuItemChecked(pDynamicStaticMenu, ID_STATIC);
			}
		}
	}
	return FALSE;
}

void CMainFrame::OnToggleDynamic() {
	CMenu* g_pMenu = GetMenu();
	if (g_pMenu) {
		// 查找 "编辑" 菜单
		CMenu* pEditMenu = nullptr;
		pEditMenu = g_pMenu->GetSubMenu(2);
		if (pEditMenu) {
			// 查找 "右键动态或静态" 子菜单

			pDynamicStaticMenu = pEditMenu->GetSubMenu(2);
			if (pDynamicStaticMenu) {
				UINT state = pDynamicStaticMenu->GetMenuState(ID_DYNAMIC, MF_BYCOMMAND);
				if (state != (UINT)-1) {
					BOOL isChecked = (state & MF_CHECKED) != 0;
					pDynamicStaticMenu->CheckMenuItem(ID_DYNAMIC, MF_BYCOMMAND | (isChecked ? MF_UNCHECKED : MF_CHECKED));
					pDynamicStaticMenu->CheckMenuItem(ID_STATIC, MF_BYCOMMAND | (isChecked ? MF_CHECKED : MF_UNCHECKED));
				}
			}
		}
	}
}

void CMainFrame::OnToggleStatic() {
	CMenu* g_pMenu = GetMenu();
	if (g_pMenu) {
		// 查找 "编辑" 菜单
		CMenu* pEditMenu = nullptr;
		pEditMenu = g_pMenu->GetSubMenu(2);
		if (pEditMenu) {
			// 查找 "右键动态或静态" 子菜单

			pDynamicStaticMenu = pEditMenu->GetSubMenu(2);
			if (pDynamicStaticMenu) {
				// 判断 "动态" 菜单项是否被勾选
				UINT state = pDynamicStaticMenu->GetMenuState(ID_STATIC, MF_BYCOMMAND);
				if (state != (UINT)-1) {
					BOOL isChecked = (state & MF_CHECKED) != 0;
					pDynamicStaticMenu->CheckMenuItem(ID_STATIC, MF_BYCOMMAND | (isChecked ? MF_UNCHECKED : MF_CHECKED));
					pDynamicStaticMenu->CheckMenuItem(ID_DYNAMIC, MF_BYCOMMAND | (isChecked ? MF_CHECKED : MF_UNCHECKED));
				}
			}
		}
	}
}